﻿namespace Sofire.Data
{
    using System;
    using System.Collections.Generic;

    /// <summary>
    /// 引擎管理器基类。
    /// </summary>
    /// <typeparam name="TEngine">引擎的类型。</typeparam>
    /// <typeparam name="TCommand">命令的类型。</typeparam>
    public abstract class EngineManagerBase<TEngine, TCommand> : ExecuteEventObjectBase<TCommand>, IEnumerable<TEngine>
        where TEngine : class
        where TCommand : ExecuteCommandBase
    {
        #region Fields

        /// <summary>
        /// 获取主要业务引擎的标识名称。
        /// </summary>
        public const string SourceBusiness = "Business";

        /// <summary>
        /// 获取历史业务引擎的标识名称。
        /// </summary>
        public const string SourceHistory = "History";

        /// <summary>
        /// 获取平台引擎的标识名称。
        /// </summary>
        public const string SourcePlatform = "Platform";

        private TEngine _Business;
        private TEngine _History;
        private Dictionary<string, TEngine> _internalManager = new Dictionary<string, TEngine>(StringComparer.OrdinalIgnoreCase);
        private TEngine _Platform;

        #endregion Fields

        #region Properties

        /// <summary>
        /// 获取主要业务的引擎。
        /// </summary>
        public TEngine Business
        {
            get
            {
                return this._Business;
            }
        }

        /// <summary>
        /// 获取引擎的数目。
        /// </summary>
        public int Count
        {
            get
            {
                return this._internalManager.Count;
            }
        }

        /// <summary>
        /// 获取历史业务的引擎。
        /// </summary>
        public TEngine History
        {
            get
            {
                return this._History;
            }
        }

        /// <summary>
        /// 获取引擎的所有名称。
        /// </summary>
        public IEnumerable<string> Names
        {
            get
            {
                return this._internalManager.Keys;
            }
        }

        /// <summary>
        /// 获取平台的引擎。
        /// </summary>
        public TEngine Platform
        {
            get
            {
                return this._Platform;
            }
        }

        #endregion Properties

        #region Indexers

        /// <summary>
        /// 获取指定标识的引擎。
        /// </summary>
        /// <param name="name">引擎的标识名称。</param>
        public TEngine this[string name]
        {
            get
            {
                TEngine proxy;
                if(this._internalManager.TryGetValue(name, out proxy))
                {
                    return proxy;
                }
                throw new ArgumentException("无法找到标识为“" + name + "”的引擎。", "name");
            }
        }

        #endregion Indexers

        #region Methods

        /// <summary>
        /// 清空所有引擎。
        /// </summary>
        public virtual void Clear()
        {
            this._Business = null;
            this._History = null;
            this._Platform = null;
            this._internalManager.Clear();
        }

        IEnumerator<TEngine> IEnumerable<TEngine>.GetEnumerator()
        {
            return this._internalManager.Values.GetEnumerator();
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return this._internalManager.Values.GetEnumerator();
        }

        /// <summary>
        /// 添加一个引擎。
        /// </summary>
        /// <param name="name">引擎的标识。</param>
        /// <param name="engine">引擎的实例。</param>
        protected virtual void AddEngine(string name, TEngine engine)
        {
            switch(name)
            {
                case SourceBusiness:
                    this._Business = engine;
                    break;
                case SourceHistory:
                    this._History = engine;
                    break;
                case SourcePlatform:
                    this._Platform = engine;
                    break;
            }
            this._internalManager.Add(name, engine);
        }

        #endregion Methods
    }
}